package cn.cdm.service;

import cn.cdm.dao.OrderDao;
import cn.cdm.domain.MiaoshaOrder;
import cn.cdm.domain.MiaoshaUser;
import cn.cdm.domain.OrderInfo;
import cn.cdm.redis.GoodsKey;
import cn.cdm.redis.RedisService;
import cn.cdm.vo.GoodsVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Slf4j
@Service
public class OrderService {

	@Autowired
	private RedisService redisService;
	
	@Autowired
	OrderDao orderDao;
	
	public MiaoshaOrder getMiaoshaOrderByUserIdGoodsId(long userId, long goodsId) {
		return orderDao.getMiaoshaOrderByUserIdGoodsId(userId, goodsId);
	}

	/**
	 * miaoshaOrder表中设置用户id、商品id的唯一索引，解决同一个用户重复秒杀成功的Bug。
	 * UNIQUE KEY `u_uid_gid` (`user_id`,`goods_id`) USING BTREE COMMENT '唯一索引-解决某个用户重复秒杀'
	 * @param user
	 * @param goods
	 * @return
	 */
	@Transactional
	public OrderInfo createOrder(MiaoshaUser user, GoodsVo goods) {
		OrderInfo orderInfo = new OrderInfo();
		orderInfo.setCreateDate(new Date());
		orderInfo.setDeliveryAddrId(0L);
		orderInfo.setGoodsCount(1);
		orderInfo.setGoodsId(goods.getId());
		orderInfo.setGoodsName(goods.getGoodsName());
		// 设置秒杀商品价格
		orderInfo.setGoodsPrice(goods.getMiaoshaPrice());
		orderInfo.setOrderChannel(1);
		// 订单信息状态：0新建未支付
		orderInfo.setStatus(0);
		orderInfo.setUserId(user.getId());
		// 插入订单信息至订单信息表中
		orderDao.insert(orderInfo);

		// 根据订单id号，创建秒杀订单对象，插入该对象到秒杀订单表中
		MiaoshaOrder miaoshaOrder = new MiaoshaOrder();
		miaoshaOrder.setGoodsId(goods.getId());
		// todo 从订单表中获取该主键id。使用到了Mybatis中的@SelectKey
		miaoshaOrder.setOrderId(orderInfo.getId());
		miaoshaOrder.setUserId(user.getId());
		// 插入重复的键，会抛出DuplicateKeyException异常，声明式事务会拿到这个异常，对数据库进行回滚，最终这个重复键的异常接着会抛给最上层的调用者。
		// todo @Transactional仍会将异常交给最上层的调用者
		try {
			orderDao.insertMiaoshaOrder(miaoshaOrder);
		} catch (Exception e) {
			log.error("插入键重复，秒杀订单：{}；异常：", miaoshaOrder, e);
			// 捕获异常后，需手动抛出该异常，声明式事务注解才会生效
			throw e;
		}

		redisService.set(GoodsKey.orderInfo, "" + user.getId() + "-" + goods.getId(), RedisService.beanToString(miaoshaOrder));

		return orderInfo;
	}

	// 删除订单信息表、删除秒杀订单表这两个操作，是一个事务，若其中一个操作失败，整个事务都会回滚
	@Transactional
	public void deleteOrders() {
		orderDao.deleteOrders();
		orderDao.deleteMiaoshaOrders();
	}
}
